"""
15. 三数之和
中等
相关标签
premium lock icon
相关企业
提示
给你一个整数数组 nums ，判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ，同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意：答案中不可以包含重复的三元组。

 

 

示例 1：

输入：nums = [-1,0,1,2,-1,-4]
输出：[[-1,-1,2],[-1,0,1]]
解释：
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意，输出的顺序和三元组的顺序并不重要。
示例 2：

输入：nums = [0,1,1]
输出：[]
解释：唯一可能的三元组和不为 0 。
示例 3：

输入：nums = [0,0,0]
输出：[[0,0,0]]
解释：唯一可能的三元组和为 0 。
 

提示：

3 <= nums.length <= 3000
-105 <= nums[i] <= 105
"""
from typing import List


class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        """
        双指针:固定一个节点，然后双指针，一个在最左从左往右，一个在右从右往左，去除重复的比较
        举个例子 -10 -2 -1 4 6 11
        找到11和-1后，11不在需要和其他-2的比较，只需要往里缩，找其他选项
        :param nums:
        :return:
        """
        ans = []
        nums.sort()
        len1 = len(nums)
        i = 0
        while i <len1 and nums[i]<=0:
            if i>0 and nums[i] == nums[i-1]:
                i+=1
                continue
            #双指针
            l = i + 1
            r = len1 - 1
            while l < r:
                lChange = False
                rChange = False
                s = nums[i] + nums[l] + nums[r]
                if s>0:
                    rChange = True
                elif s<0:
                    lChange = True
                else:
                    cur = [nums[i],nums[l],nums[r]]
                    ans.append(cur)
                    lChange = True
                    rChange = True
                if lChange:
                    l += 1
                    while l < len1 and nums[l] == nums[l-1]:
                        l += 1
                if rChange:
                    r -= 1
                    while r > i and nums[r] == nums[r+1]:
                        r-=1
            i+=1
        return ans

    def threeSum_res1(self, nums: [int]) -> [[int]]:
        nums.sort()
        res, k = [], 0
        for k in range(len(nums) - 2):
            if nums[k] > 0: break # 1. because of j > i > k.
            if k > 0 and nums[k] == nums[k - 1]: continue # 2. skip the same `nums[k]`.
            i, j = k + 1, len(nums) - 1
            while i < j: # 3. double pointer
                s = nums[k] + nums[i] + nums[j]
                if s < 0:
                    i += 1
                    while i < j and nums[i] == nums[i - 1]: i += 1
                elif s > 0:
                    j -= 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1
                else:
                    res.append([nums[k], nums[i], nums[j]])
                    i += 1
                    j -= 1
                    while i < j and nums[i] == nums[i - 1]: i += 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1
        return res


if __name__ == '__main__':
    s = Solution()
    # print(s.threeSum([-1,0,1,2,-1,-4]))
    # print(s.threeSum([0,1,1]))
    # print(s.threeSum([0,0,0]))
    print(s.threeSum([-100,-70,-60,110,120,130,160]))


    # list = [1,2,3]
    # #栈操作
    # list.append(4)
    # print(list)
    # print(list.pop())
    # print(list)
    # print(list.pop(0))
    # print(list)



